package com.grant.code.controller;

import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseEvent;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 文件树控制器 - 负责处理目录树相关的所有功能
 * 包括目录树的初始化、导航和选择操作
 */
public class FileTreeController {

    @FXML private TreeView<File> directoryTree;
    @FXML private Label statusBar;
    
    // 回调接口，用于通知文件夹选择事件
    private DirectorySelectedCallback directorySelectedCallback;

    /**
     * 默认构造函数
     */
    public FileTreeController() {
        // 用于JavaFX FXML注入
    }

    /**
     * 带参数的构造函数
     * @param directoryTree 目录树组件
     * @param statusBar 状态栏
     */
    public FileTreeController(TreeView<File> directoryTree, Label statusBar) {
        this.directoryTree = directoryTree;
        this.statusBar = statusBar;
        initialize();
    }
    
    /**
     * 初始化文件树控制器
     */
    public void initialize() {
        initDirectoryTree();
    }
    
    /**
     * 设置目录选择回调
     * @param callback 目录选择回调接口
     */
    public void setDirectorySelectedCallback(DirectorySelectedCallback callback) {
        this.directorySelectedCallback = callback;
    }
    
    /**
     * 初始化目录树
     */
    private void initDirectoryTree() {
        // 获取所有根目录（磁盘）
        File[] roots = File.listRoots();
        TreeItem<File> root = new TreeItem<>(new File("Computer"));
        root.setExpanded(true);
        for (File file : roots) {
            root.getChildren().add(createNode(file));
        }
        directoryTree.setRoot(root);
        directoryTree.setShowRoot(false);

        // 添加展开监听器
        root.addEventHandler(TreeItem.<File>branchExpandedEvent(), event -> {
            TreeItem<File> item = event.getTreeItem();
            if (item != null && !item.isLeaf()) { // 确保只有非叶子节点才构建子节点
                item.getChildren().setAll(buildChildren(item));
            }
        });
    }
    
    /**
     * 创建树节点
     * @param file 文件对象
     * @return 树节点
     */
    private TreeItem<File> createNode(File file) {
        TreeItem<File> item = new TreeItem<>(file) {
            private boolean isFirstTimeChildren = true;
            private boolean isLeaf;

            @Override
            public ObservableList<TreeItem<File>> getChildren() {
                if (isFirstTimeChildren) {
                    isFirstTimeChildren = false;
                    File[] children = file.listFiles(File::isDirectory); // 只显示目录
                    isLeaf = children == null || children.length == 0;
                    if (!isLeaf) {
                        super.getChildren().setAll(buildChildren(this));
                    }
                }
                return super.getChildren();
            }

            @Override
            public boolean isLeaf() {
                return isLeaf;
            }
        };
        return item;
    }
    
    /**
     * 构建子节点
     * @param item 父节点
     * @return 子节点列表
     */
    private List<TreeItem<File>> buildChildren(TreeItem<File> item) {
        return Arrays.stream(Objects.requireNonNull(item.getValue().listFiles(File::isDirectory))) // 只显示目录
                .map(this::createNode)
                .collect(Collectors.toList());
    }
    
    /**
     * 处理目录点击事件
     * @param event 鼠标事件
     */
    @FXML
    public void handleDirectoryClick(MouseEvent event) {
        TreeItem<File> item = directoryTree.getSelectionModel().getSelectedItem();
        if (item != null && event.getClickCount() == 1) {
            if (directorySelectedCallback != null) {
                directorySelectedCallback.onDirectorySelected(item.getValue());
            }
        }
    }
    
    /**
     * 获取选中的目录
     * @return 选中的目录，如果没有选中则返回null
     */
    public File getSelectedDirectory() {
        TreeItem<File> selectedItem = directoryTree.getSelectionModel().getSelectedItem();
        return selectedItem != null ? selectedItem.getValue() : null;
    }
    
    /**
     * 目录选择回调接口
     */
    public interface DirectorySelectedCallback {
        /**
         * 当目录被选中时调用
         * @param directory 选中的目录
         */
        void onDirectorySelected(File directory);
    }
} 